package com.cc.mall.web;

import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cc.common.utils.R;
import com.cc.common.utils.ResponseData;
import com.cc.mall.config.AlipayTemplate;
import com.cc.mall.entity.OnlineOrderEntity;
import com.cc.mall.entity.OnlineOrderProductEntity;
import com.cc.mall.entity.ProductDetailEntity;
import com.cc.mall.feign.UserFeign;
import com.cc.mall.service.OnlineOrderProductService;
import com.cc.mall.service.OnlineOrderService;
import com.cc.mall.service.ProductDetailService;
import com.cc.mall.vo.*;
import com.cc.user.entity.ScheduleEntity;
import com.cc.user.entity.UserEntity;
import com.netflix.client.http.HttpRequest;
import io.swagger.annotations.*;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/mall")
@Api(tags = "订单")
public class OrderController {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserFeign userFeign;

    @Autowired
    private OnlineOrderService orderService;

    @Autowired
    private OnlineOrderProductService onlineOrderProductService;

    @Autowired
    private AlipayTemplate alipayTemplate;

    @Autowired
    private ProductDetailService productDetailService;


    // 创建订单并支付（分线上：支付宝，线下：返回为客户下单)
    @ApiOperation("点击立即支付去创建订单并付款")
    @PostMapping("/createOrder")
    public ResponseData<Long> createOrder(@ApiParam("商品详情id数组") @RequestBody Long[] skuIds,
                                    HttpSession session,
                                    @ApiParam("地址id") @RequestParam(value = "rid",required = false) Long rid,
                                    @ApiParam("客户id") @RequestParam(value = "cid",required = false) Long cid) throws AlipayApiException, ExecutionException, InterruptedException {
        // todo 令牌防重
        UserEntity user = (UserEntity) session.getAttribute("loginuser");
        Long uid = user.getUid();
        // 商品是否售罄
        List<Long> numbers = productDetailService.checkProductOver(skuIds);
        for (Long number : numbers) {
            if(number <= 0){
                // 存在商品售罄
                return ResponseData.success("您的订单中有商品已售罄，请重新下单",false);
            }
        }
        Long orderId = productDetailService.createOrder(skuIds,uid,cid,rid);
        // 及时删除购物车
        BoundHashOperations<String,Object,Object> cartOps = redisTemplate.boundHashOps(uid.toString());
        for (Long skuId : skuIds) {
            cartOps.delete(skuId.toString());
        }
        return ResponseData.success(orderId); // todo
    }

    @ApiOperation("商品详情页中的立即结算")
    @PostMapping("/trade")
    public ResponseData<OrderVo> trade(@ApiParam("需要结算的商品详情id") @RequestParam("skuId") Long skuId,
                                       @ApiParam("数量") @RequestParam(value = "num",required = false,defaultValue = "1") Integer num,
                     HttpSession session){
        UserEntity user = (UserEntity) session.getAttribute("loginuser");
        Long uid = user.getUid();
        // 把改商品详情的数量改为1
        productDetailService.addToCart2(skuId,num,uid);
        Long [] skuIds = new Long[]{skuId};
        OrderVo orderVo = productDetailService.toTrade(skuIds,uid);
        return ResponseData.success(orderVo);
    }
    /**
     * 1.直接到结算页
     * 2.从去付款到结算页 TODO 是否要考虑
     * @param skuIds
     * @return
     */
    @ApiOperation("从购物车到结算页")
    @PostMapping("/toTrade")
    public ResponseData<OrderVo> toTrade(@ApiParam("需要结算的商品详情id数组") @RequestBody Long[] skuIds,
                     HttpSession session){
        UserEntity user = (UserEntity) session.getAttribute("loginuser");
        Long uid = user.getUid();
        OrderVo orderVo = productDetailService.toTrade(skuIds,uid);
        return ResponseData.success(orderVo);
    }

    // type=1员工 type=2客户
    @ApiOperation("获取用户的全部订单")
    @PostMapping("/getOrder")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "status", value = "订单状态,0：待付款1：待发货2：待收货3：已收货", paramType = "query", dataType = "Integer", required = false,allowableValues = "0,1,2,3")
    })
    public ResponseData<List<OrderVo>> getOrder(@RequestParam(value = "status",required = false) Integer status, HttpSession session) throws ExecutionException, InterruptedException {
        UserEntity user = (UserEntity) session.getAttribute("loginuser");
        Long uid = user.getUid();
        Integer type = user.getPermission();
        List<OrderVo> orderVos = productDetailService.getOrderByUid(uid,type,status);
        /*if(status != null){
            if(orderVos != null && orderVos.size()>0){
                orderVos = orderVos.stream().filter(f -> f.getStatus() == status).collect(Collectors.toList());
            }

        }*/
        return ResponseData.success(orderVos);
    }

    // 去付款的支付
    @ApiOperation("支付宝支付接口")
    @GetMapping("/payOrder")
    public ResponseData<String> payOrder(@ApiParam("线上订单id") @RequestParam("orderId") Long orderId) throws AlipayApiException {
        String orderString = productDetailService.payOrder(orderId);
       /* PayVo payVo = new PayVo();
        payVo.setBody("商品描述");
        payVo.setSubject("宣酒");
        payVo.setOut_trade_no(orderId);
        payVo.setTotal_amount("1");
        String pay = alipayTemplate.pay(payVo);*/
        return ResponseData.success(orderString); // todo
    }

    // 去付款的支付
    @ApiOperation("微信支付接口")
    @GetMapping("/payOrderWx")
    public ResponseData<Map> payOrderWx(@ApiParam("线上订单id") @RequestParam("orderId") Long orderId) {
        Map map = orderService.payOrderWx(orderId);
        return ResponseData.success(map); // todo
    }

    // 支付宝异步通知
    @ApiOperation("支付宝的异步通知")
    @PostMapping("/notifyUrl")
    public String notifyUrl(PayAsyncVo payAsyncVo, HttpServletRequest request) throws AlipayApiException {
        // todo 验签
        //获取支付宝POST过来反馈信息
        Map< String , String > params   =   new HashMap< String , String >();
        Map   requestParams   =   request . getParameterMap ();
        for  (Iterator iter = requestParams . keySet (). iterator (); iter . hasNext ();) {
            String   name   =  ( String )  iter . next ();
            String []  values   =  ( String [])  requestParams . get ( name );
            String   valueStr   =   "" ;
            for  ( int   i   =   0 ;  i   <   values . length ;  i ++ ) {
                valueStr   =  ( i   ==   values . length   -   1 )  ?   valueStr   +   values [ i ]
                        :  valueStr   +   values [ i ]  +   "," ;
            }
            // 乱码解决，这段代码在出现乱码时使用。
            // valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params . put ( name ,  valueStr );
        }
        //切记alipaypublickey是支付宝的公钥，请去open.alipay.com对应应用下查看。
        //boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)
        boolean   flag   =   AlipaySignature. rsaCheckV1 ( params ,  alipayTemplate.getAlipay_public_key() ,  alipayTemplate.getCharset() , "RSA2" );
        // 验证成功之后
        if(flag){
            // 验证成功
            System.out.println(payAsyncVo);
            Integer orderStatus = 0;
            if(payAsyncVo.getTrade_status().equals("TRADE_SUCCESS")){
                // 支付成功
                orderStatus = 1;
                Long orderId = Long.parseLong(payAsyncVo.getOut_trade_no());
                OnlineOrderEntity onlineOrderEntity = orderService.getById(orderId);
                onlineOrderEntity.setOnlineOrderStatus(orderStatus);
                onlineOrderEntity.setAmountsPaid(onlineOrderEntity.getAmountsPayable());
                orderService.updateById(onlineOrderEntity);
                ScheduleEntity scheduleEntity = new ScheduleEntity();
                scheduleEntity.setUid(onlineOrderEntity.getUid());
                scheduleEntity.setCreatetime(new Date());
                scheduleEntity.setScheduleStatus(0);
                scheduleEntity.setContent("您的订单【"+ orderId +"】【已付款】");
                userFeign.save(scheduleEntity);
                // 扣库存
                List<CartItem> cartItemList = (List<CartItem>) redisTemplate.opsForValue().get(payAsyncVo.getOut_trade_no());
                productDetailService.koukucun2(cartItemList);
                // 将其删除
                redisTemplate.delete(payAsyncVo.getOut_trade_no());
                return "success";
            }else if (payAsyncVo.getTrade_status().equals("TRADE_CLOSED")){
                Long orderId = Long.parseLong(payAsyncVo.getOut_trade_no());
                // 关闭订单 todo 是否删除订单以及订单详情和redis
                // 删除订单详情
                onlineOrderProductService.remove(new QueryWrapper<OnlineOrderProductEntity>().eq("ooid",orderId));
                // 删除订单
                orderService.removeById(orderId);
                // 将redis其删除
                redisTemplate.delete(payAsyncVo.getOut_trade_no());
                return "success";
            }else if(payAsyncVo.getTrade_status().equals("TRADE_FINISHED")){
                // 订单完成
                return "success";
            }
            else{
                return "fail";
            }
        }else {
            // 验证不通过
            return "fail";
        }

    }

    // 微信的异步通知
    @ApiOperation("微信的异步通知")
    @PostMapping("/notifyUrl2")
    public String notifyUrl2(PayAsyncVo payAsyncVo, HttpServletRequest request) throws AlipayApiException {
        return "";
    }

    // 删除订单
    @ApiOperation("根据订单id删除订单以及对应的订单详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderType", value = "订单类型1:线下;2：线下", dataType = "Integer", required = true,allowableValues = "1,2")
    })
    @GetMapping("/removeOrder")
    public ResponseData removeOrder(@ApiParam("订单id") @RequestParam("orderId") Long orderId,
                         @RequestParam("orderType") Integer orderType){
        productDetailService.removeOrder(orderId,orderType);
        return ResponseData.success("成功删除订单",true);
    }

    // 确认收货
    @ApiOperation("根据订单id修改订单状态为确认收货")
    @GetMapping("/confirmRecieve")
    public ResponseData confirmRecieve(@ApiParam("订单id") @RequestParam("orderId") Long orderId,
                                       @ApiParam("订单类型1:线上;2：线下") @RequestParam("orderType") Integer orderType){
        productDetailService.confirmRecieve(orderId,orderType);
        return ResponseData.success("确认收货",true);
    }


}
